#include "BackendWnd.h"
#include "ui_BackendWnd.h"

#include <QButtonGroup>
#include <QAbstractButton>
#include <QPushButton>

#include <QStandardItem>
#include <QStandardItemModel>
#include <QHeaderView>

#include <QTimer>
#include <QComboBox>
#include <QListView>
#include <QCompleter>
#include <QDebug>

#include "AppModel.h"

#include "commondefine.h"
#include "tablehelper.h"
#include "excelhelper.h"

#include "TestRecordManager.h"
#include "SNRecordManager.h"
#include "MsgWnd.h"

#define CB_ALL_ITEM                 "ALL"
#define CB_DEFAULT_ITEM             "NONE"

BackendWnd::BackendWnd(QWidget *parent) :
    QWidget(parent)
  , ui(new Ui::BackendWnd)
  , btnGpBackendSel(new QButtonGroup())
  , btnGpRecordSel(nullptr)
  , model_all_record_result_(new QStandardItemModel)
  , model_sn_record_result_(new QStandardItemModel)
  , completer_all_page_account(new QCompleter(this))
  , completer_all_page_sn(new QCompleter(this))
  , completer_sn_page_account(new QCompleter(this))
  , completer_sn_page_sn(new QCompleter(this))
{
    ui->setupUi(this);

    init();

    QObject::connect(GlobalSignal::getInstance(), &GlobalSignal::switchLanguage, this, &BackendWnd::lang_change);

    QObject::connect(GlobalSignal::getInstance(), &GlobalSignal::confirm_type, this, &BackendWnd::event_confirm_type);
}

BackendWnd::~BackendWnd()
{
    QObject::disconnect(GlobalSignal::getInstance(), &GlobalSignal::switchLanguage, this, &BackendWnd::lang_change);

    QObject::disconnect(GlobalSignal::getInstance(), &GlobalSignal::confirm_type, this, &BackendWnd::event_confirm_type);

    all_record_vec_.clear();
    sn_record_vec_.clear();

    if (btnGpBackendSel)
        disconnect(btnGpBackendSel, SIGNAL(buttonClicked(int)), this, SLOT(event_backend_select_btn_clicked(int)));

    if (btnGpRecordSel)
        disconnect(btnGpRecordSel, SIGNAL(buttonClicked(int)), this, SLOT(event_navi_btn_clicked(int)));

    if (btnGpBackendSel)
    {
        delete btnGpBackendSel;
        btnGpBackendSel = Q_NULLPTR;
    }

    if (btnGpRecordSel)
    {
        delete btnGpRecordSel;
        btnGpRecordSel = Q_NULLPTR;
    }

    if (model_all_record_result_)
    {
        delete model_all_record_result_;
        model_all_record_result_ = Q_NULLPTR;
    }

    if (model_sn_record_result_)
    {
        delete model_sn_record_result_;
        model_sn_record_result_ = Q_NULLPTR;
    }

    delete ui;
}

void BackendWnd::lang_change()
{
    if (ui) ui->retranslateUi(this);

    init_table_view();

    init_all_page_combo_normal();
}

void BackendWnd::event_confirm_type(zl::EUserConfirmType type, bool confirm)
{
    if (!confirm) return;

    if (type == EUserConfirmType_DeleteAction)
    {
        QStringList record_list;

        TableHelper::getSelectedRowsData(ui->tb_all_record_result, 0, record_list);

        if (record_list.isEmpty()) return;

        auto ret = TestRecordManager::getInstance()->RemoveTestRecords(record_list);
        if (ret != zl::EResult_Success)
        {
            qDebug() << "[ERROR]" << "delete selected record failed, ret:" << ret;
            return;
        }

        QEventLoop loop1;
        QTimer::singleShot(200, &loop1, SLOT(quit()));
        loop1.exec();

        on_btn_all_record_query_clicked();
    }
    else if (type == EUserConfirmType_DeleteSN)
    {
        QStringList record_list;

        TableHelper::getSelectedRowsData(ui->tb_sn_record_result, 0, record_list);

        if (record_list.isEmpty()) return;

        auto ret = SNRecordManager::getInstance()->RemoveSNRecords(record_list);
        if (ret != zl::EResult_Success)
        {
            qDebug() << "[ERROR]" << "delete selected record failed, ret:" << ret;
            return;
        }

        QEventLoop loop1;
        QTimer::singleShot(200, &loop1, SLOT(quit()));
        loop1.exec();

        on_btn_sn_record_query_clicked();
    }
}

void BackendWnd::ShowBackendPage()
{
    ui->btn_page_record->setEnabled(true);
    ui->btn_page_advance->setEnabled(true);

    SetBackendPage(zl::EBP_Select_page);
}

void BackendWnd::SetBackendPage(zl::EBP backendPage)
{
    ui->stackedWidget_bk->setCurrentIndex(backendPage);

    if (backendPage == EBP_Record_page)
    {
        update_combo_completer();
    }
}

void BackendWnd::NotifyQuitBackend()
{

}

void BackendWnd::LoadData()
{
    update_advance_info();
}

void BackendWnd::UpdatePanelAdvance()
{
    update_advance_info();
}

void BackendWnd::init()
{
    init_select_page();

    init_table_view();

    init_record_page();

    init_advance_page();
}

void BackendWnd::init_table_view()
{
    // 操作记录 查询结果列表
    QStringList list_all_record = { tr("Index"), tr("Time"), tr("Account"), tr("Action"), tr("Ret"), tr("SN")};
    QVector<int> widths_all_record = {80, 240, 240, 240, 240, 400};

    TableHelper::initTableHeader(list_all_record, widths_all_record, model_all_record_result_, ui->tb_all_record_result);
//    ui->tb_all_record_result->horizontalHeader()->setSectionResizeMode(7, QHeaderView::Stretch);

    // SN记录 查询结果列表
    QStringList list_sn_record = { tr("Index"), tr("Time"), tr("Account"), tr("SN"), tr("SN_T")};
    QVector<int> widths_sn_record = {80, 240, 240, 400, 400};

    TableHelper::initTableHeader(list_sn_record, widths_sn_record, model_sn_record_result_, ui->tb_sn_record_result);

}

void BackendWnd::init_select_page()
{
    // connect
    QList<QPushButton*> btnList;
    btnList << ui->btn_page_record << ui->btn_page_advance;

    // ***index从1开始 0为select page***
    for (int i = 0; i < btnList.size(); i++)
        btnGpBackendSel->addButton(btnList.at(i), i+1);

    connect(btnGpBackendSel, SIGNAL(buttonClicked(int)), this, SLOT(event_backend_select_btn_clicked(int)));
}

void BackendWnd::init_record_page()
{
    btnGpRecordSel = new QButtonGroup(this);
    btnGpRecordSel->addButton(ui->btn_navi_action, 0);
    btnGpRecordSel->addButton(ui->btn_navi_sn, 1);

    connect(btnGpRecordSel, SIGNAL(buttonClicked(int)), this, SLOT(event_navi_btn_clicked(int)));

    init_all_page_combo_normal();
    init_all_page_combo_completer();

    init_all_page_time_select();

    init_sn_page_combo_completer();

    init_sn_page_time_select();
}

void BackendWnd::init_all_page_time_select()
{
    ui->edt_all_record_begin_date->setDateTime(QDateTime::currentDateTime());
    ui->edt_all_record_end_date->setDateTime(QDateTime::currentDateTime().addDays(1));
}

void BackendWnd::init_sn_page_time_select()
{
    ui->edt_sn_record_begin_date->setDateTime(QDateTime::currentDateTime());
    ui->edt_sn_record_end_date->setDateTime(QDateTime::currentDateTime().addDays(1));
}

void BackendWnd::init_all_page_combo_normal()
{
    ui->combo_all_record_action_type->clear();
    ui->combo_all_record_action_type->insertItem(0, tr(CB_ALL_ITEM), -1);
    ui->combo_all_record_action_type->insertItem(1, tr("Read SN"), zl::ESNWT_ActionType_Read);
    ui->combo_all_record_action_type->insertItem(2, tr("Erase SN"), zl::ESNWT_ActionType_Erase);
    ui->combo_all_record_action_type->insertItem(3, tr("Erase Mcu"), zl::ESNWT_ActionType_Mcu);
    ui->combo_all_record_action_type->insertItem(4, tr("Write SN"), zl::ESNWT_ActionType_OneKeyWrite);

    ui->combo_all_record_result_type->clear();
    ui->combo_all_record_result_type->insertItem(0, tr(CB_ALL_ITEM), -1);
    ui->combo_all_record_result_type->insertItem(1, tr("Success"), zl::ESNWT_ResultType_Success);
    ui->combo_all_record_result_type->insertItem(2, tr("Failed"), zl::ESNWT_ResultType_Failed);
}

void BackendWnd::init_all_page_combo_completer()
{
    QAbstractItemView* account_list_view = completer_all_page_account->popup();
    QFont account_font = account_list_view->font();
    account_font.setPixelSize(32);
    account_list_view->setFont(account_font);

    ui->combo_all_record_account->setCompleter(completer_all_page_account);
    ui->combo_all_record_account->setCurrentText("");


    QAbstractItemView* sn_list_view = completer_all_page_sn->popup();
    QFont sn_font = sn_list_view->font();
    sn_font.setPixelSize(32);
    sn_list_view->setFont(sn_font);

    ui->combo_all_record_sn->setCompleter(completer_all_page_sn);
    ui->combo_all_record_sn->setCurrentText("");
}

void BackendWnd::init_sn_page_combo_completer()
{
    QAbstractItemView* account_list_view = completer_sn_page_account->popup();
    QFont account_font = account_list_view->font();
    account_font.setPixelSize(32);
    account_list_view->setFont(account_font);

    ui->combo_sn_record_account->setCompleter(completer_sn_page_account);
    ui->combo_sn_record_account->setCurrentText("");


    QAbstractItemView* sn_list_view = completer_sn_page_sn->popup();
    QFont sn_font = sn_list_view->font();
    sn_font.setPixelSize(32);
    sn_list_view->setFont(sn_font);

    ui->combo_sn_record_sn->setCompleter(completer_sn_page_sn);
    ui->combo_sn_record_sn->setCurrentText("");
}

void BackendWnd::init_advance_page()
{
    ui->cb_serialport->clear();
    ui->cb_baudrate->clear();

    ui->cb_serialport->addItem(tr(CB_DEFAULT_ITEM), "");
    ui->cb_baudrate->addItem(tr(CB_DEFAULT_ITEM), "");


    for (int i = 0; i < 30; i++)
    {
        QString port_name = QString("COM%1").arg(i+1);

        ui->cb_serialport->addItem(port_name, port_name);
    }

    QStringList baudrate;
    baudrate << "4800" << "9600" << "19200" << "38400" << "43000" << "56000" << "57600" << "115200";

    for (int i = 0; i < baudrate.size(); i++)
    {
        QString baud_rate = baudrate.at(i);

        ui->cb_baudrate->addItem(baud_rate, baud_rate);
    }

    ui->edt_sn_address->setValidator(new QRegExpValidator(QRegExp(REG_EXP_SN_ADDRS), this));
    ui->edt_sn_rule_len->setValidator(new QRegExpValidator(QRegExp(REG_EXP_SN_LEN), this));
    ui->edt_sn_mem_len->setValidator(new QRegExpValidator(QRegExp(REG_EXP_SN_LEN), this));
}

void BackendWnd::update_combo_completer()
{
    update_all_page_combo_completer();

    update_sn_page_combo_completer();
}

void BackendWnd::update_all_page_combo_completer()
{
    QStringList account_list, sn_list;

    auto ret = TestRecordManager::getInstance()->GetComboCompleterInfo(account_list, sn_list);
    if (ret != zl::EResult_Success)
    {
        qDebug() << "[INFO]" << "get combo completer info failed: " << ret;
        return;
    }

    ui->combo_all_record_account->clear();
    ui->combo_all_record_account->insertItem(0, tr(CB_ALL_ITEM));

    for (int i = 0; i < account_list.size(); i++)
    {
        ui->combo_all_record_account->insertItem(i+1, account_list.at(i));
    }

    ui->combo_all_record_account->setCurrentIndex(0);

    completer_all_page_account->setModel(ui->combo_all_record_account->model());
    ui->combo_all_record_account->setCurrentText(tr(CB_ALL_ITEM));



    ui->combo_all_record_sn->clear();
    ui->combo_all_record_sn->insertItem(0, tr(CB_ALL_ITEM));

    for (int i = 0; i < sn_list.size(); i++)
    {
        ui->combo_all_record_sn->insertItem(i+1, sn_list.at(i));
    }

    ui->combo_all_record_sn->setCurrentIndex(0);

    completer_all_page_sn->setModel(ui->combo_all_record_sn->model());
    ui->combo_all_record_sn->setCurrentText(tr(CB_ALL_ITEM));
}

void BackendWnd::update_sn_page_combo_completer()
{
    QStringList account_list, sn_list;

    auto ret = SNRecordManager::getInstance()->GetComboCompleterInfo(account_list, sn_list);
    if (ret != zl::EResult_Success)
    {
        qDebug() << "[INFO]" << "get combo completer info failed: " << ret;
        return;
    }

    ui->combo_sn_record_account->clear();
    ui->combo_sn_record_account->insertItem(0, tr(CB_ALL_ITEM));

    for (int i = 0; i < account_list.size(); i++)
    {
        ui->combo_sn_record_account->insertItem(i+1, account_list.at(i));
    }

    ui->combo_sn_record_account->setCurrentIndex(0);

    completer_sn_page_account->setModel(ui->combo_sn_record_account->model());
    ui->combo_sn_record_account->setCurrentText(tr(CB_ALL_ITEM));



    ui->combo_sn_record_sn->clear();
    ui->combo_sn_record_sn->insertItem(0, tr(CB_ALL_ITEM));

    for (int i = 0; i < sn_list.size(); i++)
    {
        ui->combo_sn_record_sn->insertItem(i+1, sn_list.at(i));
    }

    ui->combo_sn_record_sn->setCurrentIndex(0);

    completer_sn_page_sn->setModel(ui->combo_sn_record_sn->model());
    ui->combo_sn_record_sn->setCurrentText(tr(CB_ALL_ITEM));
}

void BackendWnd::update_advance_info()
{
    // 更新监控板配置信息
    auto monitor_config = APPMODEL()->Config().monitor_config;

    if (monitor_config.port.isEmpty())
    {
        ui->cb_serialport->setCurrentIndex(0);
    }
    else
    {
        int32_t index = ui->cb_serialport->findText(monitor_config.port);
        ui->cb_serialport->setCurrentIndex(index==-1?0:index);
    }

    if (monitor_config.baud_rate.isEmpty())
    {
        ui->cb_baudrate->setCurrentIndex(0);
    }
    else
    {
        int32_t index = ui->cb_baudrate->findText(monitor_config.baud_rate);
        ui->cb_baudrate->setCurrentIndex(index==-1?0:index);
    }

    ui->cb_enable_use_monitor->setChecked(monitor_config.enable_monitor_control_power);


    // 更新sn配置信息
    auto sn_config = APPMODEL()->Config().sn_config;

    ui->edt_sn_address->setText(sn_config.address);
    ui->edt_sn_rule_len->setText(QString::number(sn_config.sn_rule_len));
    ui->edt_sn_mem_len->setText(QString::number(sn_config.sn_mem_bytes_len));
}

void BackendWnd::event_backend_select_btn_clicked(int index)
{
    if (index <= 0) return;

    emit GlobalSignal::getInstance()->backend_page_change(zl::EBP(index));
}

void BackendWnd::event_navi_btn_clicked(int index)
{
    ui->stackedWidget->setCurrentIndex(index);
}

void BackendWnd::on_btn_all_record_query_clicked()
{
    QString begdt = ui->edt_all_record_begin_date->date().toString("yyyy-MM-dd");
    QString enddt = ui->edt_all_record_end_date->date().toString("yyyy-MM-dd");

    ESNWT_ActionType action_type = (ESNWT_ActionType)ui->combo_all_record_action_type->currentData().toInt();
    ESNWT_ResultType result_type = (ESNWT_ResultType)ui->combo_all_record_result_type->currentData().toInt();

    QString account = ui->combo_all_record_account->currentText();
    QString sn = ui->combo_all_record_sn->currentText();

    if (account.compare(CB_ALL_ITEM) == 0) account.clear();
    if (sn.compare(CB_ALL_ITEM) == 0) sn.clear();

    all_record_vec_.clear();

    int32_t ret = zl::TestRecordManager::getInstance()->GetAllRecord(
        all_record_vec_,
        begdt,
        enddt,
        action_type,
        result_type,
        account,
        sn);

    if (ret != zl::EResult_Success)
    {
        MsgWnd::ShowNormalInfo(QObject::tr("Query Failed"));
        return;
    }

    auto pfconvert = [](int32_t v) -> QString {
        switch (v)
        {
        case zl::ESNWT_ActionType_Read:                 return tr("Read SN");
        case zl::ESNWT_ActionType_Erase:                return tr("Erase SN");
        case zl::ESNWT_ActionType_Mcu:                  return tr("Erase Mcu");
        case zl::ESNWT_ActionType_OneKeyWrite:          return tr("Write SN");

        default: return tr("Unknown");
        }
    };

    auto pfconvert2 = [](int32_t v) -> QString {
        switch (v)
        {
        case zl::ESNWT_ResultType_Success:              return tr("Success");
        case zl::ESNWT_ResultType_Failed:               return tr("Failed");

        default: return tr("Unknown");
        }
    };

    int32_t index = 0;

    auto funcAddItem = [&](const zl::RecordInfo& record)
    {
        QList<QStandardItem*> row;

        QStandardItem* first = new QStandardItem(QString::number(++index));
        first->setData(record.record_id);
        first->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
        row.append(first);

        QStandardItem* second = new QStandardItem(record.action_time);
        second->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
        row.append(second);

        QStandardItem* third = new QStandardItem(record.account);
        third->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
        row.append(third);

        QStandardItem* fourth = new QStandardItem(pfconvert(record.action_type));
        fourth->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
        row.append(fourth);

        QStandardItem* fifth = new QStandardItem(pfconvert2(record.result_type));
        fifth->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
        row.append(fifth);

        QStandardItem* sixth = new QStandardItem(record.sn_info);
        sixth->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
        row.append(sixth);

        model_all_record_result_->appendRow(row);
    };

    // update table order
    TableHelper::readyUpdate(model_all_record_result_, ui->tb_all_record_result);

    foreach(const zl::RecordInfo record, all_record_vec_)
    {
        funcAddItem(record);
    }

    TableHelper::finishUpdate(model_all_record_result_, ui->tb_all_record_result);
}

void BackendWnd::on_btn_all_record_export_excel_clicked()
{
    int row = 0;
    if (model_all_record_result_) row = model_all_record_result_->rowCount();

    if (all_record_vec_.isEmpty() || row < 1)
    {
        MsgWnd::ShowNormalInfo(QObject::tr("Please query data first"));
        return;
    }

    auto pfconvert = [](int32_t v) -> QString {
        switch (v)
        {
        case zl::ESNWT_ActionType_Read:                 return tr("Read SN");
        case zl::ESNWT_ActionType_Erase:                return tr("Erase SN");
        case zl::ESNWT_ActionType_Mcu:                  return tr("Erase Mcu");
        case zl::ESNWT_ActionType_OneKeyWrite:          return tr("Write SN");

        default: return tr("Unknown");
        }
    };

    auto pfconvert2 = [](int32_t v) -> QString {
        switch (v)
        {
        case zl::ESNWT_ResultType_Success:              return tr("Success");
        case zl::ESNWT_ResultType_Failed:               return tr("Failed");

        default: return tr("Unknown");
        }
    };


    QList<QStringList> data_list;

    int32_t index = 0;

    auto funcAddItem = [&](const zl::RecordInfo& record)
    {
        QStringList one_data;

        one_data.append(QString::number(++index));
        one_data.append(record.action_time);
        one_data.append(record.account);
        one_data.append(pfconvert(record.action_type));
        one_data.append(pfconvert2(record.result_type));
        one_data.append(record.sn_info);

        data_list.append(one_data);
    };

    foreach(const zl::RecordInfo record, all_record_vec_)
    {
        funcAddItem(record);
    }

    bool bRet = ExcelHelper::tableToExcel(ui->tb_all_record_result, tr("Action Record"), tr("User Action Record"), &data_list);

    if(!bRet)
    {
        MsgWnd::ShowNormalInfo(QObject::tr("Export action record to excel file failed"));
        return;
    }
}

void BackendWnd::on_btn_all_record_sel_all_clicked()
{
    TableHelper::selectAllRows(model_all_record_result_, ui->tb_all_record_result);
}

void BackendWnd::on_btn_all_record_reset_selected_clicked()
{
    TableHelper::clearAllSelectedRows(model_all_record_result_, ui->tb_all_record_result);
}

void BackendWnd::on_btn_all_record_delete_clicked()
{
    QStringList record_list;

    TableHelper::getSelectedRowsData(ui->tb_all_record_result, 0, record_list);

    if (record_list.isEmpty()) return;

    MsgWnd::ConfirmDeleteActionRecord(tr("Confirm delete selected"), tr("action Record?"));
}

void BackendWnd::on_btn_sn_record_query_clicked()
{
    QString begdt = ui->edt_sn_record_begin_date->date().toString("yyyy-MM-dd");
    QString enddt = ui->edt_sn_record_end_date->date().toString("yyyy-MM-dd");

    QString account = ui->combo_sn_record_account->currentText();
    QString sn = ui->combo_sn_record_sn->currentText();

    if (account.compare(CB_ALL_ITEM) == 0) account.clear();
    if (sn.compare(CB_ALL_ITEM) == 0) sn.clear();

    sn_record_vec_.clear();

    int32_t ret = zl::SNRecordManager::getInstance()->GetAllSNRecord(
        sn_record_vec_,
        begdt,
        enddt,
        account,
        sn);

    if (ret != zl::EResult_Success)
    {
        MsgWnd::ShowNormalInfo(QObject::tr("Query Failed"));
        return;
    }

    int32_t index = 0;

    auto funcAddItem = [&](const zl::SNInfo& sn_data)
    {
        QList<QStandardItem*> row;

        QStandardItem* first = new QStandardItem(QString::number(++index));
        first->setData(sn_data.sn_info);
        first->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
        row.append(first);

        QStandardItem* second = new QStandardItem(sn_data.action_time);
        second->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
        row.append(second);

        QStandardItem* third = new QStandardItem(sn_data.account);
        third->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
        row.append(third);

        QStandardItem* fourth = new QStandardItem(sn_data.sn_info);
        fourth->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
        row.append(fourth);

        QStandardItem* fifth = new QStandardItem(sn_data.sn_total);
        fifth->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
        row.append(fifth);

        model_sn_record_result_->appendRow(row);
    };

    // update table sn
    TableHelper::readyUpdate(model_sn_record_result_, ui->tb_sn_record_result);

    foreach(const zl::SNInfo sn_data, sn_record_vec_)
    {
        funcAddItem(sn_data);
    }

    TableHelper::finishUpdate(model_sn_record_result_, ui->tb_sn_record_result);
}

void BackendWnd::on_btn_sn_record_export_excel_clicked()
{
    int row = 0;
    if (model_sn_record_result_) row = model_sn_record_result_->rowCount();

    if (sn_record_vec_.isEmpty() || row < 1)
    {
        MsgWnd::ShowNormalInfo(QObject::tr("Please query data first"));
        return;
    }

    QList<QStringList> data_list;

    int32_t index = 0;

    auto funcAddItem = [&](const zl::SNInfo& sn_data)
    {
        QStringList one_data;

        one_data.append(QString::number(++index));
        one_data.append(sn_data.action_time);
        one_data.append(sn_data.account);
        one_data.append(sn_data.sn_info);
        one_data.append(sn_data.sn_total);

        data_list.append(one_data);
    };

    foreach(const zl::SNInfo sn_data, sn_record_vec_)
    {
        funcAddItem(sn_data);
    }

    bool bRet = ExcelHelper::tableToExcel(ui->tb_sn_record_result, tr("SN Record"), tr("Used SN Record"), &data_list);

    if(!bRet)
    {
        MsgWnd::ShowNormalInfo(QObject::tr("Export sn record to excel file failed"));
        return;
    }
}

void BackendWnd::on_btn_sn_record_sel_all_clicked()
{
    TableHelper::selectAllRows(model_sn_record_result_, ui->tb_sn_record_result);
}

void BackendWnd::on_btn_sn_record_reset_selected_clicked()
{
    TableHelper::clearAllSelectedRows(model_sn_record_result_, ui->tb_sn_record_result);
}

void BackendWnd::on_btn_sn_record_delete_clicked()
{
    QStringList record_list;

    TableHelper::getSelectedRowsData(ui->tb_sn_record_result, 0, record_list);

    if (record_list.isEmpty()) return;

    MsgWnd::ConfirmDeleteSNRecord(tr("Confirm delete selected"), tr("SN Record?"));
}

void BackendWnd::on_btn_lang_cn_clicked()
{
    zl::ELanguageType cur_lang = APPMODEL()->CabinetLanguage();

    if (cur_lang == zl::ELanguageType_Cn) return;

    emit GlobalSignal::getInstance()->select_language(zl::ELanguageType_Cn);
}

void BackendWnd::on_btn_lang_en_clicked()
{
    zl::ELanguageType cur_lang = APPMODEL()->CabinetLanguage();

    if (cur_lang == zl::ELanguageType_En) return;

    emit GlobalSignal::getInstance()->select_language(zl::ELanguageType_En);
}

void BackendWnd::on_btn_save_advance_clicked()
{
    auto config = APPMODEL()->Config();
    bool modified = false;

    QString cur_port_name = ui->cb_serialport->currentData().toString().trimmed();
    QString cur_baud_rate = ui->cb_baudrate->currentData().toString().trimmed();
    bool cur_enable_use = ui->cb_enable_use_monitor->isChecked();

    QString cur_address = ui->edt_sn_address->text().trimmed();
    QString cur_rule_len = ui->edt_sn_rule_len->text().trimmed();
    QString cur_mem_len = ui->edt_sn_mem_len->text().trimmed();

    bool rule_len_ok, mem_len_ok;

    int32_t rule_len = cur_rule_len.toInt(&rule_len_ok);
    int32_t mem_len = cur_mem_len.toInt(&mem_len_ok);

    QRegExp re_address(REG_EXP_SN_ADDRS), re_len(REG_EXP_SN_LEN);

    if (cur_address.isEmpty() || !re_address.exactMatch(cur_address))
    {
        MsgWnd::ShowNormalInfo(QObject::tr("Input address is illegal"));
        return;
    }

    if (cur_rule_len.isEmpty() || !re_len.exactMatch(cur_rule_len) || !rule_len_ok)
    {
        MsgWnd::ShowNormalInfo(QObject::tr("Input sn rule len is illegal"));
        return;
    }

    if (cur_mem_len.isEmpty() || !re_len.exactMatch(cur_mem_len) || !mem_len_ok)
    {
        MsgWnd::ShowNormalInfo(QObject::tr("Input sn memory len is illegal"));
        return;
    }

    if (config.monitor_config.port.compare(cur_port_name) != 0
            || config.monitor_config.baud_rate.compare(cur_baud_rate) != 0
            || config.monitor_config.enable_monitor_control_power != cur_enable_use)
    {
        modified = true;
    }

    if (config.sn_config.address.compare(cur_address, Qt::CaseInsensitive) != 0
            || config.sn_config.sn_rule_len != rule_len
            || config.sn_config.sn_mem_bytes_len != mem_len
            )
    {
        modified = true;
    }

    config.monitor_config.port = cur_port_name;
    config.monitor_config.baud_rate = cur_baud_rate;
    config.monitor_config.enable_monitor_control_power = cur_enable_use;

    config.sn_config.address = cur_address;
    config.sn_config.sn_rule_len = rule_len;
    config.sn_config.sn_mem_bytes_len = mem_len;

    APPMODEL()->SetConfig(config);

    auto ret = APPMODEL()->SaveAppConfiguration();
    if (ret != zl::EResult_Success)
    {
        MsgWnd::ShowNormalInfo(QObject::tr("Save config info failed"));
    }
    else
    {
        if (modified)
            emit configChanged();
    }
}
